package engine;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.websocket.WebSocket;
import org.eclipse.jetty.websocket.WebSocketServlet;
/**
 * Jetty WebSocketServlet implementation class Engine
 */
public class Engine extends WebSocketServlet {
	private static final long serialVersionUID = 1L;
	protected Messenger msgr;
	protected Game game;
	protected Thread msgrThread;
	protected boolean gameStarted = false;
	protected boolean msgrStarted = false;
	private EngineWebSocket connection;


	/**
	 * @see WebSocketServlet#WebSocketServlet()
	 */
	public Engine() {
		super();
		// TODO Auto-generated constructor stub
	}
	private final Set<EngineWebSocket> members = new CopyOnWriteArraySet<EngineWebSocket>();

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String action = request.getParameter("param");
		HttpSession session = request.getSession(true);
		//log("Session is: " + session.getId());
		log("Action is: " + action);
		if (action.equals("isGameRunning")){
			PrintWriter pw = response.getWriter();
			if (this.gameStarted){
				pw.println("running = true");
			}
			else {
				pw.println("running = false");
			}
			pw.close();
		}
		PrintWriter pw = response.getWriter();
		pw.println("OK");
		pw.close();
		if (action.equals("restore")){
			synchronized(game){
				game.notify();
			}
			//TODO:
			game.restoreState();
		}
		if (action.equals("start")) {
			//game.startGame(game);
			if (this.gameStarted){
				game.stop();
				//gameThread.stop();
				msgr.stop();
				//msgrThread.stop();
				this.gameStarted = false;
				this.msgrStarted = false;
			}
			msgr = new Messenger(connection);
			msgrThread = new Thread(msgr,"[msgr]");
			//msgrThread.setDaemon(true);
			msgrThread.start();
			game = new Game(connection);
			game.messenger = msgr;
			game.startGame();
			log("Game started");
			this.gameStarted = true;
			this.msgrStarted = true;
			
		}

		if (this.gameStarted){
			if (action.equals("fold")) {
				synchronized(game){
					game.notify();
				}
				game.human.fold();
				log("Player folds");
				
			}
			else if (action.equals("raise")){
				synchronized(game){
					game.notify();
				}
				game.human.raise();
				log("Player raises");
			}
			else if (action.equals("check")){
				synchronized(game){
					game.notify();
				}
				game.human.checkCall();
				log("Players check/calls");
			}
			else if (action.equals("leave")){
				game.stop();
				msgr.stop();
				this.gameStarted = false;
				this.msgrStarted = false;
				log("Player leaves");
			}
			else if (action.equals("msg")){
				System.out.println(request.getParameter("message"));
				
			}
		}
		
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		getServletContext().getNamedDispatcher("default").forward(request, response);
	}

	/*
	 * @see org.eclipse.jetty.websocket.WebSocketServlet#doWebSocketConnect(javax.servlet.http.HttpServletRequest, java.lang.String)
	 */
	public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) {
		return new EngineWebSocket();
	}

	class EngineWebSocket implements WebSocket {
		private Outbound outbound;
		
		public void sendMessage(String message){
			try {
				this.outbound.sendMessage(message);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		public void onConnect(Outbound outbound) {
			this.outbound = outbound;
			members.add(this);
			connection = this;
		}

		/*
		 * @see org.eclipse.jetty.websocket.WebSocket#onMessage(byte, byte[],
		 * int, int)
		 */
		public void onMessage(byte frame, byte[] data, int offset, int length) {
		}

		/*
		 * @see org.eclipse.jetty.websocket.WebSocket#onMessage(byte,
		 * java.lang.String)
		 */
		public void onMessage(byte frame, String data) {
			System.out.println("DATA: " + data);
			if (data.equals("isGameRunning")){
				if (gameStarted){
					this.sendMessage("running = true");
				}
				else {
					try {
						this.outbound.sendMessage("running = false");
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
			else if (data.equals("restore")){
				msgr.setResponse(this);
				synchronized(game){
					game.notify();
				}
				//TODO:
				game.restoreState();
			}
			else if (data.equals("start")) {
				//game.startGame(game);
				if (gameStarted){
					game.stop();
					//gameThread.stop();
					msgr.stop();
					//msgrThread.stop();
					gameStarted = false;
					msgrStarted = false;
				}
				msgr = new Messenger(this);
				msgrThread = new Thread(msgr,"[msgr]");
				//msgrThread.setDaemon(true);
				msgrThread.start();
				game = new Game(this);
				game.messenger = msgr;
				game.startGame();
				log("Game started");
				gameStarted = true;
				msgrStarted = true;
			}
			else if (gameStarted){
				if (data.equals("fold")) {
					synchronized(game){
						game.notify();
					}
					game.human.fold();
					log("Player folds");
					
				}
				else if (data.equals("raise")){
					synchronized(game){
						game.notify();
					}
					game.human.raise();
					log("Player raises");
				}
				else if (data.equals("check")){
					synchronized(game){
						game.notify();
					}
					game.human.checkCall();
					log("Players check/calls");
				}
				else if (data.equals("leave")){
					game.stop();
					msgr.stop();
					gameStarted = false;
					msgrStarted = false;
					log("Player leaves");
				}
			}
			else {
				//tegu chatiga
			}
			
		}

		/*
		 * @see org.eclipse.jetty.websocket.WebSocket#onDisconnect()
		 */
		public void onDisconnect() {
			members.remove(this);
		}

		/*
		 * 
		 * @see org.eclipse.jetty.websocket.WebSocket#onFragment(boolean, byte,
		 * byte[], int, int)
		 */
		public void onFragment(boolean more, byte opcode, byte[] data,
				int offset, int length) {

		}

		public void onClose(int arg0, String arg1) {
			// TODO Auto-generated method stub

		}

		public void onOpen(Connection arg0) {
			// TODO Auto-generated method stub
		}

		public void endGame() {
			gameStarted = false;
			game.stop();
		}

	

}


}
